package com.ant.storage.common.aop;

import com.ant.storage.mapper.OperLogMapper;
import com.ant.storage.pojo.OperLog;
import com.ant.storage.utils.IpUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

// https://blog.csdn.net/weixin_47480200/article/details/137615951s
/**
 * @author hzd
 * @version 1.0
 * @date 2024/6/27 11:46
 */
@Aspect
@Component
public class LogAspect {

    @Pointcut("@annotation(com.ant.storage.common.aop.Log)")
    public void pointCut(){}

    @Autowired
    HttpServletRequest request;

    @Resource
    OperLogMapper  operLogMapper;

    @After(value = "pointCut()")
    public void afterLogWrite(JoinPoint joinPoint){
        // 创建日志对象
        OperLog operLog = new OperLog();
        // 获取我们调用的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        // 获取方法上的Log注解，因为我们要获取注解中的一些信息
        Log log = method.getAnnotation(Log.class);

        // 获取我们调用的类的名称
        String className = joinPoint.getTarget().getClass().getName();
        // 获取调用的方法的名称
        String methodName = method.getName();
        // 重新修改一下我们调用的方法 是全路径的
        methodName = className + methodName;

        // 获取方法的参数
        Object[] args = joinPoint.getArgs();
        ObjectMapper objectMapper = new ObjectMapper();
        String params = "";
        try {
            params =  objectMapper.writeValueAsString(args);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        // 获取注解中的操作名称
        String operation = log.operation();
        // 获取注解中的操作类型
        String businessType = log.businessType().toString();

        // 这里的操作人员仅靠后端是写不了的  需要前端的token认证  我直接把操作人员改为admin
        String username = "admin";

        // 获取ip地址
        String ipAddress = IpUtil.getIpAddr(request);
        operLog.setBusinessType(businessType);
        operLog.setOperation(operation);
        operLog.setMethod(methodName);
        operLog.setParams(params);
        operLog.setIp(ipAddress);
        operLog.setOperName(username);
        operLog.setCreateTime(LocalDateTime.now());
        operLogMapper.insert(operLog);

    }
}
